<script setup lang="ts">
  import { useSlots, ref } from 'vue'
  import { ElInput, ElButton, vLoading } from 'element-plus'
  import Search from '@iconify-icons/tabler/search'
  import { IconType, IconsType, IconifyUtil, IconTypeConst, SIcon } from '@xtail/vue3'
  import { XIconSet } from '../XIconSet'
  import { IconSetOnlineSearchIconifyPropsType } from './types'

  defineOptions({
    name: 'XIconSetOnlineSearchIconify'
  })

  const props = withDefaults(defineProps<IconSetOnlineSearchIconifyPropsType>(), {
    size: 'default',
    filter: false,
    pagination: true,
    searchResultLimit: 150,
    searchClass: '',
    searchStyle: '',
    searchPrefixIptProps: {} as any,
    searchPrefixClass: '',
    searchPrefixStyle: '',
    searchIconIptProps: {} as any,
    searchIconClass: '',
    searchIconStyle: '',
    searchBtnProps: {} as any
  })

  const value = defineModel<IconType>({ default: null })

  const slots = useSlots()

  const searchPrefix = ref('')
  const searchIcon = ref('')
  const icons = ref<IconsType>([])
  const isSearching = ref(false)
  const isSearchError = ref(false)
  const searchErrorMsg = ref('')
  const search = async () => {
    if (!searchIcon.value?.trim?.()) return
    if (isSearching.value) return
    isSearchError.value = false
    isSearching.value = true
    try {
      icons.value = (
        await IconifyUtil.searchIcons(searchIcon.value, {
          prefixes: searchPrefix.value ? [searchPrefix.value] : [],
          limit: Math.min(props.searchResultLimit, 999)
        })
      ).icons.map(icon => {
        return {
          iconName: icon,
          iconType: IconTypeConst.ICONIFY,
          iconProps: { icon }
        }
      })
    } catch (e: any) {
      isSearchError.value = true
      searchErrorMsg.value = e.message ?? e
    } finally {
      isSearching.value = false
    }
  }
</script>

<template>
  <div v-loading="isSearching" class="x-icon-set-online-search-iconify">
    <div class="x-icon-set-online-search-iconify__search" :class="searchClass" :style="searchStyle">
      <el-input
        v-bind="{
          ...searchPrefixIptProps,
          size: searchPrefixIptProps.size ?? size,
          placeholder: searchPrefixIptProps.placeholder ?? '图标前缀搜索',
          clearable: true
        }"
        v-model="searchPrefix"
        class="x-icon-set-online-search-iconify__search-prefix"
        :class="searchPrefixClass"
        :style="searchPrefixStyle"
        @keydown.enter="search"
      >
        <template v-if="slots['search-prefix-ipt-prefix']" #prefix>
          <slot name="search-prefix-ipt-prefix" />
        </template>
        <template v-if="slots['search-prefix-ipt-suffix']" #suffix>
          <slot name="search-prefix-ipt-suffix" />
        </template>
        <template v-if="slots['search-prefix-ipt-prepend']" #prepend>
          <slot name="search-prefix-ipt-prepend" />
        </template>
        <template v-if="slots['search-prefix-ipt-append']" #append>
          <slot name="search-prefix-ipt-append" />
        </template>
      </el-input>
      <el-input
        v-bind="{
          ...searchIconIptProps,
          size: searchIconIptProps.size ?? size,
          placeholder: searchIconIptProps.placeholder ?? '(必填)图标名称搜索',
          clearable: true
        }"
        v-model="searchIcon"
        class="x-icon-set-online-search-iconify__search-icon"
        :class="searchIconClass"
        :style="searchIconStyle"
        @keydown.enter="search"
      >
        <template v-if="slots['search-icon-ipt-prefix']" #prefix>
          <slot name="search-icon-ipt-prefix" />
        </template>
        <template v-if="slots['search-icon-ipt-suffix']" #suffix>
          <slot name="search-icon-ipt-suffix" />
        </template>
        <template v-if="slots['search-icon-ipt-prepend']" #prepend>
          <slot name="search-icon-ipt-prepend" />
        </template>
        <template v-if="slots['search-icon-ipt-append']" #append>
          <slot name="search-icon-ipt-append" />
        </template>
      </el-input>
      <el-button
        v-bind="{
          ...searchBtnProps,
          size: searchBtnProps.size ?? size,
          type: searchBtnProps.type ?? 'primary',
          plain: searchBtnProps.plain ?? true
        }"
        @click="search"
      >
        <template #icon>
          <slot name="search-btn-icon">
            <s-icon :icon-props="{ icon: Search }" />
          </slot>
        </template>
      </el-button>
    </div>
    <x-icon-set
      v-model="value"
      :icons="icons"
      :size="size"
      :filter="filter"
      :filter-ipt-props="filterIptProps"
      :filter-btn-props="filterBtnProps"
      :filter-class="filterClass"
      :filter-style="filterStyle"
      :scrollbar-props="scrollbarProps"
      :grid-auto-fill-cols-props="gridAutoFillColsProps"
      :icon-btn-props="iconBtnProps"
      :icon-btn-selected-props="iconBtnSelectedProps"
      :pagination="pagination"
      :default-page-size="defaultPageSize"
      :pagination-props="paginationProps"
      :pagination-scrollbar-props="paginationScrollbarProps"
      :pagination-scrollbar-class="paginationScrollbarClass"
      :pagination-scrollbar-style="paginationScrollbarStyle"
      :empty-props="emptyProps"
      :result-props="
        isSearchError
          ? {
              icon: 'error',
              title: '图标搜索失败',
              subTitle: searchErrorMsg,
              ...(resultProps ?? {})
            }
          : undefined
      "
    >
      <template v-if="slots['filter-ipt-prefix']" #filter-ipt-prefix>
        <slot name="filter-ipt-prefix" />
      </template>
      <template v-if="slots['filter-ipt-suffix']" #filter-ipt-suffix>
        <slot name="filter-ipt-suffix" />
      </template>
      <template v-if="slots['filter-ipt-prepend']" #filter-ipt-prepend>
        <slot name="filter-ipt-prepend" />
      </template>
      <template v-if="slots['filter-ipt-append']" #filter-ipt-append>
        <slot name="filter-ipt-append" />
      </template>
      <template v-if="slots['filter-btn-icon']" #filter-btn-icon>
        <slot name="filter-btn-icon" />
      </template>
      <template v-if="slots['search-result-icon']" #result-icon>
        <slot name="search-result-icon" />
      </template>
      <template v-if="slots['search-result-title']" #result-title>
        <slot name="search-result-title" />
      </template>
      <template v-if="slots['search-result-sub-title']" #result-sub-title>
        <slot name="search-result-sub-title" />
      </template>
      <template v-if="slots['search-result-extra']" #result-extra>
        <slot name="search-result-extra" />
      </template>
      <template v-if="slots['empty-bottom']" #empty-bottom>
        <slot name="empty-bottom" />
      </template>
      <template v-if="slots['empty-image']" #empty-image>
        <slot name="empty-image" />
      </template>
      <template v-if="slots['empty-description']" #empty-description>
        <slot name="empty-description" />
      </template>
    </x-icon-set>
  </div>
</template>

<style lang="scss">
  @use './style' as *;
</style>
